//
//  Speak.swift
//  TextSpeak
//
//  Created by nhope on 2017/9/8.
//  Copyright © 2017年 nhope. All rights reserved.
//

import UIKit
import AVFoundation
import MediaPlayer

class Speech: NSObject {

    fileprivate let speechAynthesizer = AVSpeechSynthesizer()
    /// 记录系统音量
    fileprivate var systemVolume: Float = 0.5
    
    func speak(_ text: String) {
        if speechAynthesizer.isSpeaking {
            // 如果当前正在播放则停止播放
            // 如果未停止,将会在当前播放完毕后再播放新的语音
            speechAynthesizer.stopSpeaking(at: .immediate)
        }
        let utterance = AVSpeechUtterance(string: text)
        // 语速,0~1.0
        utterance.rate = AVSpeechUtteranceDefaultSpeechRate
        // 设置播放语言
        utterance.voice = AVSpeechSynthesisVoice(language: "zh-CN")
        // 开始播放语音
        speechAynthesizer.delegate = self
        speechAynthesizer.speak(utterance)
    }
    
    /// 设置音量阀值
    ///
    /// - Parameter isRestore: 是否为恢复系统音量
    fileprivate func setVolumeThreshold(_ isRestore:Bool=false) {
        // 如果需要隐藏系统音量框的话,需确保`isHidden`为false
        // 然后可通过将frame设置为屏幕外或者将alpha设置为0.01
        let volumeView = MPVolumeView(frame: .zero)
        volumeView.isHidden = false
        volumeView.alpha = 0.01
        UIApplication.shared.keyWindow?.addSubview(volumeView)

        DispatchQueue.main.asyncAfter(deadline: .now()+0.1) { [weak self] in
            for view in volumeView.subviews {
                // ObjC需这样判断[view.class.description isEqualToString:@"MPVolumeSlider"]
                if NSStringFromClass(view.classForCoder) == "MPVolumeSlider" {
                    let slider = view as! UISlider
                    if isRestore {
                        // 恢复系统音量
                        slider.setValue(self?.systemVolume ?? 0.5, animated: false)
                    } else {
                        // 设置固定音量(可以防止用户将手机音量设置过小时听不到语音)
                        self?.systemVolume = slider.value
                        slider.setValue(0.8, animated: false)
                    }
                    slider.sendActions(for: .touchUpInside)
                }
            }
            DispatchQueue.main.asyncAfter(deadline: .now()+0.1, execute: {
                volumeView.removeFromSuperview()
            })
        }
    }
    
}


extension Speech: AVSpeechSynthesizerDelegate {
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
        setVolumeThreshold()
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
        setVolumeThreshold(true)
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) {
        setVolumeThreshold()
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
        setVolumeThreshold(true)
    }
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        setVolumeThreshold(true)
    }
    
}
